package com.blog.blogservice.infra.mybatis.interceptor;

import com.blog.blogservice.domain.entity.AdminClass;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.Date;

/**
 * mybatis拦截器
 *
 * @author guanglin.ma
 * @date 2024-04-08 14:25
 */
@Component
@Intercepts({@Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class}),
        @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})})
public class MybatisInterceptor implements Interceptor {

    Logger logger = LoggerFactory.getLogger(MybatisInterceptor.class);

    ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public Object intercept(Invocation invocation) throws Throwable {

        for (Object o : invocation.getArgs()) {
            System.out.println("测试" + o);
        }

        MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
        Object parameterObject = invocation.getArgs()[1];
        //判断哪种类型sql
        switch (mappedStatement.getSqlCommandType().name()) {
            case "INSERT":
                System.out.println("拦截器：insert");
                createAdminClassField(parameterObject);
                break;
            case "UPDATE":
                System.out.println("拦截器：update");
//                upfateField(invocation);
                break;
            case "DELETE":
                System.out.println("delete");
                break;
            case "SELECT":
                System.out.println("select");
                break;
            default:
                System.out.println("other");
        }
        return invocation.proceed();
    }

    private String getSql(MappedStatement mappedStatement, Object parameterObject) {
        String sql = mappedStatement.getBoundSql(parameterObject).getSql();
        //转小写，替换空格、制表符、换页符等
        return sql.toLowerCase().replaceAll("\\s+", " ");
    }

    /**
     * ) values (
     */
    private static final String SQL_STATEMENT_PATTERN_VALUES = "\\)\\s*values?\\s*\\(";

    private Object createAdminClassField(Object parameterObject) {
        AdminClass adminClass = (AdminClass) parameterObject;
        adminClass.setCreateTime(new Date());
        adminClass.setUpdateTime(new Date());
        adminClass.setUpdateBy(-100);
        adminClass.setVersionNum(0);
        adminClass.setDeleted(0);
        parameterObject = adminClass;
        return parameterObject;
    }

//    private Object upfateField(Invocation invocation) throws NoSuchFieldException, IllegalAccessException, ClassNotFoundException {
//        invocation.getMethod().getParameters();
//        MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
//        Class classType = Class.forName(mappedStatement.getParameterMap().getType().getTypeName());
//        TableInfo tableInfo= TableInfoHelper.getTableInfo(classType);
////        tableInfo.getFieldList().stream().findFirst()
////                .ifPresent(j -> strictFillStrategy(metaObject, fieldName, i.getFieldVal()));
//        Field field = classType.getSuperclass().getDeclaredField("updateTime");
//        field.setAccessible(true);
//        field.set(Date.class, new Date());
//
//        return null;
//    }
}
